home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / editors / emacs / xemacs / xemacs-1.006 / xemacs-1 / lib / xemacs-19.13 / lisp / packages / func-menu.el < prev    next >
Encoding:
Text File  |  1995-08-08  |  68.6 KB  |  1,863 lines

  1. ;;; func-menu.el         --- Jump to a function within a buffer.
  2. ;;;
  3. ;;; David Hughes <ukchugd@ukpmr.cs.philips.nl>
  4. ;;; Last modified: David Hughes 7th August 1995
  5. ;;; Version: 2.32
  6. ;;; Keywords: tools, c, lisp
  7. ;;;
  8. ;;; This program is free software; you can redistribute it and/or modify
  9. ;;; it under the terms of the GNU General Public License as published by
  10. ;;; the Free Software Foundation; either version 2, or (at your option)
  11. ;;; any later version.
  12. ;;;
  13. ;;; This program is distributed in the hope that it will be useful,
  14. ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. ;;; GNU General Public License for more details.
  17. ;;;
  18. ;;; You should have received a copy of the GNU General Public License
  19. ;;; along with this program; if not, write to the Free Software
  20. ;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21. ;;;
  22. ;;; Synched up with: Not in FSF.
  23. ;;;
  24. ;;; Installation:
  25. ;;; =============
  26. ;;; (require 'func-menu)
  27. ;;; (define-key global-map 'f8 'function-menu)
  28. ;;; (add-hook 'find-file-hooks 'fume-add-menubar-entry)
  29. ;;; (define-key global-map "\C-cl" 'fume-list-functions)
  30. ;;; (define-key global-map "\C-cg" 'fume-prompt-function-goto)
  31. ;;; (define-key global-map '(shift button3) 'mouse-function-menu)
  32. ;;; (define-key global-map '(meta  button1) 'fume-mouse-function-goto)
  33. ;;;
  34. ;;; Description:
  35. ;;; ============
  36. ;;; Suppose you have a file with a lot of functions in it. Well, this package
  37. ;;; makes it easy to jump to any of those functions. The names of the
  38. ;;; functions in the current buffer are automatically put into a popup menu,
  39. ;;; you select one of the function-names and the point is moved to that very
  40. ;;; function. The mark is pushed on the mark-ring, so you can easily go back
  41. ;;; to where you were. Alternatively, you can use enter the name of the
  42. ;;; desired function via the minibuffer which offers completing read input. In
  43. ;;; addition, the name of the function before point is optionally displayed in
  44. ;;; the modeline.
  45. ;;;
  46. ;;; Support for non X Windows versions of Emacs:
  47. ;;; ============================================
  48. ;;; This package can also be used for non X versions of Emacs. In this case,
  49. ;;; only modeline display and completing read input from the minibuffer are
  50. ;;; possible.
  51. ;;;
  52. ;;; Modes supported:
  53. ;;; ================
  54. ;;; Ada, Assembly, Bacis2, BibTex, C++, C, Dired, Ehdm, ELisp, FORTRAN, Ksh,
  55. ;;; Latex, Lelisp, Makefile, Maple, Modula2, Modula3, Outline, Pascal, Perl,
  56. ;;; Postscript, Prolog, PVS, Python, SGML, Scheme, Tcl, Verilog
  57. ;;;
  58. ;;; Acknowledgements:
  59. ;;; =================
  60. ;;;
  61. ;;; Idea for jumping directly with a mouse click
  62. ;;; Marc Paquette <Marc.Paquette@Softimage.COM>
  63. ;;;
  64. ;;; Prolog mode additions based on functions for Postscript mode
  65. ;;; Laszlo Teleki <laszlo@ipb.uni-bonn.de>
  66. ;;;
  67. ;;; Idea for displaying function name in modeline
  68. ;;; Paul Filipski <filipski@blackhawk.com>
  69. ;;;
  70. ;;; Fame mode support
  71. ;;; Cooper Vertz <cooper@prod2.imsi.com>
  72. ;;;
  73. ;;; Made fume-match-find-next-function-name iterative, not recursive, to avoid
  74. ;;; blowing out the emacs stack on big files with lots of prototypes.
  75. ;;; Joe Marshall <jrm@odi.com>
  76. ;;;
  77. ;;; Verilog support
  78. ;;; Matt Sale <mdsale@icdc.delcoelect.com>
  79. ;;;
  80. ;;; Minibuffer interface & Pascal support
  81. ;;; Espen Skoglund <espensk@stud.cs.uit.no>
  82. ;;;
  83. ;;; Python support
  84. ;;; Shuichi Koga <skoga@virginia.edu>
  85. ;;;
  86. ;;; Maple support
  87. ;;; Luc Tancredi <Luc.Tancredi@sophia.inria.fr>
  88. ;;;
  89. ;;; Combined Tcl and C++ function finder
  90. ;;; Andy Piper <ajp@eng.cam.ac.uk>
  91. ;;;
  92. ;;; Perl Support
  93. ;;; Alex Rezinsky <alexr@msil.sps.mot.com>
  94. ;;; Michael Lamoureux <lamour@engin.umich.edu>
  95. ;;;
  96. ;;; Suggested mouse interface
  97. ;;; Raymond L. Toy <toy@soho.crd.ge.com>
  98. ;;;
  99. ;;; Dired support
  100. ;;; Improved modula support
  101. ;;; Numerous code cleanups
  102. ;;; Norbert Kiesel <norbert@i3.informatik.rwth-aachen.de>
  103. ;;;
  104. ;;; Makefile support
  105. ;;; Suggested multi-choice sublisting
  106. ;;; Paul Filipski & Anthony Girardin <{filipski,girardin}@blackhawk.com>
  107. ;;;
  108. ;;; Suggestions for menubar entry
  109. ;;; Andy Piper <ajp@eng.cam.ac.uk>
  110. ;;;
  111. ;;; Ada support
  112. ;;; Scott Evans  <gse@ocsystems.com>
  113. ;;; Michael Polo <mikep@polo.mn.org> <mikep@cfsmo.honeywell.com>
  114. ;;;
  115. ;;; Scheme, BibTeX, Ehdm & PVS support
  116. ;;; C. Michael Holloway <c.m.holloway@larc.nasa.gov>
  117. ;;;
  118. ;;; Modula support
  119. ;;; Geoffrey Wyant <gwyant@cloyd.east.sun.com>
  120. ;;;
  121. ;;; SGML support; submenu indexing
  122. ;;; Thomas Plass <thomas.plass@mid-heidelberg.de>
  123. ;;;
  124. ;;; Extensions to fume-function-name-regexp-lisp
  125. ;;; Kari Heinola <kph@dpe.fi>
  126. ;;; Milo A. Chan <chan@jpmorgan.com>
  127. ;;; Cedric Beust <Cedric.Beust@sophia.inria.fr>
  128. ;;; Joachim Krumnow <krumnow@srsir02.ext.sap-ag.de>
  129. ;;;
  130. ;;; ksh support
  131. ;;; Philippe Bondono <bondono@vnet.ibm.com>
  132. ;;;
  133. ;;; FORTRAN support
  134. ;;; Paul Emsley <paule@chem.gla.ac.uk>
  135. ;;; Raymond L. Toy <toy@soho.crd.ge.com>
  136. ;;; Richard Cognot <cognot@elfgrc.co.uk>
  137. ;;; Greg Sjaardema <gdsjaar@sandia.gov>
  138. ;;;
  139. ;;; Latex support
  140. ;;; Wolfgang Mettbach <wolle@uni-paderborn.de>
  141. ;;; Paolo Frasconi <paolo@mcculloch.ing.unifi.it>
  142. ;;; C. Michael Holloway <c.m.holloway@larc.nasa.gov>
  143. ;;; Philippe Queinnec <queinnec@cenatls.cena.dgac.fr>
  144. ;;;
  145. ;;; Assembly support
  146. ;;; Bob Weiner <weiner@mot.com>
  147. ;;;
  148. ;;; Removal of cl dependencies
  149. ;;; Russell Ritchie <russell@gssec.bt.co.uk>
  150. ;;;
  151. ;;; C++ mode enhancemencements for func-menu
  152. ;;; Andy Piper      <ajp@eng.cam.ac.uk>
  153. ;;; Kevin R. Powell <powell@csl.ncsa.uiuc.edu>
  154. ;;; Mats Lidell     <mats.lidell@eua.ericsson.se>
  155. ;;; Mike Battaglia  <mbattagl@spd.dsccc.com>
  156. ;;; Oliver Schittko <schittko@fokus.gmd.de>
  157. ;;; Russell Ritchie <russell@gssec.bt.co.uk>
  158. ;;;
  159. ;;; Tcl mode additions for func-menu
  160. ;;; Andy Piper <ajp@eng.cam.ac.uk>
  161. ;;; Jean-Michel Augusto <augusto@eurecom.fr>
  162. ;;; Dr P.G. Sjoerdsma <pgs1002@esc.cam.ac.uk>
  163. ;;;
  164. ;;; Postscript mode additions for func-menu
  165. ;;; Leigh Klotz <klotz@adoc.xerox.com>
  166. ;;;
  167. ;;; Suggestions for popup menu positioning
  168. ;;; Marc Gemis <makke@wins.uia.ac.be>
  169. ;;;
  170. ;;; Original FSF package
  171. ;;; Ake Stenhoff <etxaksf@aom.ericsson.se>
  172.  
  173. ;;; Code
  174.  
  175. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  176. ;;;;;;;;;;;;;;;;;;;;;;;;  Environment Initialisation  ;;;;;;;;;;;;;;;;;;;;;;
  177. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  178.  
  179. (defconst fume-version "2.32")
  180.  
  181. (defconst fume-running-xemacs (string-match "XEmacs\\|Lucid" emacs-version))
  182.  
  183. (defmacro fume-defvar-local (var value &optional doc)
  184.   "Defines SYMBOL as an advertised variable.
  185. Performs a defvar, then executes `make-variable-buffer-local' on
  186. the variable.  Also sets the `permanent-local' property, so that
  187. `kill-all-local-variables' (called by major-mode setting commands)
  188. won't destroy func-menu control variables."
  189.   (` (progn
  190.        (if (, doc)
  191.            (defvar (, var) (, value) (, doc))
  192.          (defvar (, var) (, value)))
  193.        (make-variable-buffer-local '(, var))
  194.        (put '(, var) 'permanent-local t))))
  195.  
  196. (byte-compiler-options
  197.   (optimize t)
  198.   (new-bytecodes t)
  199.   (warnings (- free-vars unresolved)))
  200.  
  201. ;;; Backward compatability
  202. ;;;
  203. (or (fboundp 'selected-frame)
  204.     (defalias 'selected-frame 'selected-screen))
  205.  
  206. (defconst fume-not-tty
  207.   (or (and (fboundp 'device-type) (not (eq 'tty (device-type))))
  208.       (and (symbol-value 'window-system) t))) ; obsolete test
  209.  
  210. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  211. ;;;;;;;;;;;;;;;;;;;;;;;;;;  Customizable Variables  ;;;;;;;;;;;;;;;;;;;;;;;;
  212. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  213.  
  214. (defvar fume-auto-position-popup t
  215.   "*Set to nil if you don't want the menu to appear in the corner of the window
  216. in which case it will track the mouse position instead.")
  217.  
  218. (defvar fume-display-in-modeline-p t
  219.   "*Set to nil if you don't want the function name appearing in the modeline")
  220.  
  221. (defvar fume-buffer-name "*Function List*"
  222.   "Name of buffer used to list functions when fume-list-functions called")
  223.  
  224. (fume-defvar-local
  225.  fume-menubar-menu-name "Functions"
  226.  "*Set this to the string you want to appear in the menubar")
  227.  
  228. (defvar fume-menubar-menu-location "File"
  229.   "*Set this nil if you want the menu to appear last on the menubar.
  230. Otherwise set this to the menu you want \"Functions\" to appear in front of.")
  231.  
  232. (defvar fume-max-items 25
  233.   "*Maximum number of elements in a function (sub)menu.")
  234.  
  235. (defvar fume-fn-window-position 3
  236.   "*Number of lines from top of window at which to show function.")
  237.  
  238. (defvar fume-index-method 3
  239.   "*Set this to the method number you want used.
  240.  
  241. Methods currently supported:
  242. 0 = if you want submenu names to be numbered
  243. 1 = if you want submenu range indicated by first character
  244. 2 = if you want submenu range indicated by first 10 characters
  245. 3 = if you want submenu range indicated by as many characters as needed")
  246.  
  247. (defvar fume-scanning-message "Scanning buffer... (%3d%%)"
  248.   "*Set to nil if you don't want progress messages during manual scanning
  249. of the buffer.")
  250.  
  251. (defvar fume-rescanning-message nil
  252.   "*Set to non-nil if you want progress messages during automatic scanning
  253. of the buffer. For example \"Re-Scanning buffer...\"")
  254.  
  255. (fume-defvar-local
  256.  fume-sort-function 'fume-sort-by-name
  257.  "*The function to use for sorting the function menu.
  258.  
  259. Set this to nil if you don't want any sorting (faster).
  260. The items in the menu are then presented in the order they were found
  261. in the buffer.
  262.  
  263. The function should take two arguments and return T if the first
  264. element should come before the second.  The arguments are cons cells;
  265. (NAME . POSITION).  Look at 'fume-sort-by-name' for an example.")
  266.  
  267. (fume-defvar-local
  268.  fume-rescan-buffer-hook nil
  269.  "*Buffer local hook to call at the end of each buffer rescan")
  270.  
  271. ;;; This hook is provided for outl-mouse and must not be made buffer local as
  272. ;;; this appears to break outl-mouse for some reason.
  273. ;;;
  274. (defvar fume-found-function-hook nil
  275.   "*Hook to call after every function match.")
  276.  
  277. ;;; Idea for jumping directly with a mouse click
  278. ;;; Marc Paquette <Marc.Paquette@Softimage.COM>
  279. ;;;
  280. (defvar fume-no-prompt-on-valid-default nil
  281.   "*Set non-nil if 'fume-prompt-function-goto' should jump without prompting
  282. when a valid default exists.")
  283.  
  284. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  285. ;;;;;;;;;;;;;;;;;;;;;;;;;;  Buffer local variables  ;;;;;;;;;;;;;;;;;;;;;;;;
  286. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  287.  
  288. (fume-defvar-local
  289.  fume-funclist nil
  290.  "The latest list of function names in the buffer")
  291.  
  292. (fume-defvar-local
  293.  fume-function-name-regexp nil
  294.  "The keywords to show in a menu")
  295.  
  296. (fume-defvar-local
  297.  fume-find-next-function-name-method nil
  298.  "The function to use to find the next function name in the buffer")
  299.  
  300. (fume-defvar-local
  301.  fume-modeline-buffer-identification nil
  302.  "Storage for the original mode-line-buffer-identification")
  303.  
  304. (fume-defvar-local
  305.  fume-modeline-funclist nil
  306.  "The latest list of function names in the buffer to display in the modeline")
  307.  
  308. (fume-defvar-local
  309.  fume-funclist-dirty-p nil
  310.  "Flags whether the buffer is in need of a fresh scan")
  311.  
  312. (fume-defvar-local
  313.  fume-rescan-inhibit-p nil
  314.  "Internal variable only. DO NOT TOUCH.")
  315.  
  316. (fume-defvar-local
  317.  fume-rescan-trigger-counter 0
  318.  "Used in large buffers to optimise checking frequency")
  319.  
  320. (defvar fume-rescan-trigger-counter-buffer-size 10000
  321.   "Used to tune the frequency of automatic checks on the buffer.
  322. The function fume-rescan-buffer-trigger only works whenever the value of the
  323. variable fume-rescan-trigger-counter reaches zero, whereupon it gets reset to
  324. buffer-size/fume-rescan-trigger-counter-buffer-size.")
  325.  
  326. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  327. ;;;;;;;;;;;;;;;;;;;;;  Mode specific regexp's and hooks  ;;;;;;;;;;;;;;;;;;;
  328. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  329.  
  330. ;;; Every fume-function-name-regexp-<language> should uniquely identify a
  331. ;;; function for that certain language.
  332.  
  333. ;;; LISP
  334. ;;;
  335. ;;; Cedric Beust <Cedric.Beust@sophia.inria.fr>
  336. (defconst fume-function-name-regexp-lisp
  337.   (concat
  338.    "\\(^(defun+\\s-*[#:?A-Za-z0-9_+->]+\\s-*(\\)"
  339.    "\\|"
  340.    "\\(^(defsubst+\\s-*[#:?A-Za-z0-9_+->]+\\s-*(\\)"
  341.    "\\|"
  342.    "\\(^(defmacro+\\s-*[#:?A-Za-z0-9_+->]+\\s-*(\\)"
  343.    "\\|"
  344.    "\\(^(de+\\s-*[#:?A-Za-z0-9_+->]+\\s-*(\\)"
  345.    "\\|"
  346.    "\\(^(dmd+\\s-*[#:?A-Za-z0-9_+->]+\\s-*(\\)"
  347.    )
  348.   "Expression to get lisp function names")
  349.  
  350. ;;; C
  351. ;;;
  352. ;;; Danny Bar-Dov <danny@acet02.amil.co.il>
  353. (defconst fume-function-name-regexp-c
  354.   (concat
  355.    "^[a-zA-Z0-9]+\\s-?"                ; type specs; there can be no
  356.    "\\([a-zA-Z0-9_*]+\\s-+\\)?"        ; more than 3 tokens, right?
  357.    "\\([a-zA-Z0-9_*]+\\s-+\\)?"
  358.    "\\([*&]+\\s-*\\)?"                 ; pointer
  359.    "\\([a-zA-Z0-9_*]+\\)[ \t\n]*("     ; name
  360.    )
  361.   "Expression to get C function names")
  362.  
  363. ;;; C++
  364. ;;;
  365. ;;; Andy Piper      <ajp@eng.cam.ac.uk>
  366. ;;; Kevin R. Powell <powell@csl.ncsa.uiuc.edu>
  367. ;;; Mats Lidell     <mats.lidell@eua.ericsson.se>
  368. ;;; Mike Battaglia  <mbattagl@spd.dsccc.com>
  369. ;;; Oliver Schittko <schittko@fokus.gmd.de>
  370. (defconst fume-function-name-regexp-c++
  371.   (cons
  372.    (concat
  373.     "^\\(template\\s +<[^>]+>\\s +\\)?"          ; template formals
  374.     "\\([a-zA-Z0-9_*&<,>:]+\\s-+\\)?"            ; type specs; there can be no
  375.     "\\([a-zA-Z0-9_*&<,>\"]+\\s-+\\)?"           ; more than 3 tokens, right?
  376.     "\\([a-zA-Z0-9_*&<,>]+\\s-+\\)?"
  377.     "\\(\\([a-zA-Z0-9_~:<,>*]\\|\\(\\s +::\\s +\\)\\)+\\)"
  378.     "\\(o?perator\\s *.[^(]*\\)?\\(\\s-\\|\n\\)*(" ; name
  379.     ) 5)
  380.   "Expression to get C++ function names")
  381.  
  382. ;;; FORTRAN
  383. ;;;
  384. ;;; Paul Emsley <paule@chem.gla.ac.uk>
  385. ;;; Raymond L. Toy <toy@soho.crd.ge.com>
  386. ;;; Richard Cognot <cognot@elfgrc.co.uk>
  387. ;;; Greg Sjaardema <gdsjaar@sandia.gov>
  388. (defconst fume-function-name-regexp-fortran
  389.   (concat
  390.    ;; >= six spaces
  391.    "^      \\s-*"
  392.    ;; type specs
  393.    "+[a-zA-Z0-9*]*\\s-*"
  394.    ;; continuation lines
  395.    "\\(\n     [^ 0]\\s-*\\)*"
  396.    ;; function or subroutine
  397.    "\\(entry\\|ENTRY\\|function\\|FUNCTION\\|subroutine\\|SUBROUTINE\\)\\s-*"
  398.    ;; continuation lines
  399.    "\\(\n     [^ 0]\\s-*\\)*"
  400.    )
  401.   "Expression to get fortran function and subroutine names")
  402.  
  403. ;;; Modula
  404. (defconst fume-function-name-regexp-modula
  405.   "^\\s-*PROCEDURE\\s-+[A-Za-z0-9_-]+"
  406.   "Expression to get Modula function names")
  407.  
  408. ;;; Bacis2
  409. ;;;
  410. ;;; CV MEDUSA's 4th generation language
  411. (defconst fume-function-name-regexp-bacis
  412.   "module_define(!\\|define_constant(!\\|sys_sysdefine(!\\|<<dbgid +\\s-*"
  413.   "Expression to get Bacis2 function names")
  414.  
  415. ;;; Maple
  416. ;;;
  417. ;;; Luc Tancredi <Luc.Tancredi@sophia.inria.fr>
  418. (defvar fume-function-name-regexp-maple
  419.   "^[ \t]*[a-zA-Z0-9_]+[ \t]*:=[ \t]*proc[ \t]*("
  420.   "Expression to get maple function/procedure names")
  421.  
  422. ;;; Tcl
  423. ;;;
  424. ;;; Andy Piper <ajp@eng.cam.ac.uk>
  425. ;;; Jean-Michel Augusto <augusto@eureecom.fr>
  426. ;;; Dr P.G. Sjoerdsma <pgs1002@esc.cam.ac.uk>
  427. (defconst fume-function-name-regexp-tcl
  428.   (cons "^\\s *proc\\s +\\(\\S-+\\)\\s *{" 1)
  429.   "Expression to get Tcl function Names")
  430.  
  431. ;;; Perl
  432. ;;;
  433. ;;; Alex Rezinsky <alexr@msil.sps.mot.com>
  434. ;;; Michael Lamoureux <lamour@engin.umich.edu>
  435. (defconst fume-function-name-regexp-perl "^sub[ \t]+\\([A-Za-z0-9_]+\\)"
  436.   "Expression to get Perl function Names")
  437.  
  438. ;;; Python support
  439. ;;; Shuichi Koga <skoga@virginia.edu>
  440. ;;;
  441. (defconst fume-function-name-regexp-python
  442.   "^\\s-*\\(class\\|def\\)+\\s-*\\([A-Za-z0-9_]+\\)\\s-*[(:]"
  443.   "Expression to get Python class and function names")
  444.  
  445. ;;; Postscript
  446. ;;;
  447. ;;; Leigh L. Klotz <klotz@adoc.xerox.com>
  448. (defconst fume-function-name-regexp-postscript
  449.   "^/[^][ \t{}<>]*"
  450.   "Expression to get postscript function names")
  451.  
  452. ;;; Prolog
  453. ;;;
  454. ;;; Laszlo Teleki <laszlo@ipb.uni-bonn.de>
  455. (defconst fume-function-name-regexp-prolog
  456.   "^[a-z][a-zA-Z0-9_]+"
  457.   "Expression to get prolog fact and clause names")
  458.  
  459. ;;; Ehdm
  460. ;;;
  461. ;;; C. Michael Holloway <c.m.holloway@larc.nasa.gov>
  462. (defconst fume-function-name-regexp-ehdm
  463.   (concat
  464.    "[A-Za-z0-9_]*:[ ]*"
  465.    "\\([Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]\\|"
  466.    "[Ll][Ee][Mm][Mm][Aa]\\|"
  467.    "[Aa][Xx][Ii][Oo][Mm]\\|"
  468.    "[Pp][Rr][Oo][Vv][Ee]\\|"
  469.    "[Tt][Hh][Ee][Oo][Rr][Ee][Mm]"
  470.    "\\)"
  471.    )
  472.   "*Expression to get Ehdm function, theorems, axioms, lemmas, and proofs.")
  473.  
  474. ;;; PVS
  475. ;;;
  476. ;;; C. Michael Holloway <c.m.holloway@larc.nasa.gov>
  477. (defconst fume-function-name-regexp-pvs
  478.   (concat
  479.    "\\([A-Za-z0-9_]*:[ ]*"
  480.    "\\([Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]\\|"
  481.    "[Ll][Ee][Mm][Mm][Aa]\\|"
  482.    "[Aa][Xx][Ii][Oo][Mm]\\|"
  483.    "[Tt][Hh][Ee][Oo][Rr][Ee][Mm]\\|"
  484.    "[Ff][Or][Rr][Mm][Uu][La][Aa]"
  485.    "\\|"
  486.    "\\[.*\\]"
  487.    "\\)\\)\\|"
  488.    "[A-Za-z0-9_]*(.*)[ ]*:"
  489.    )
  490.   "*Expression to get PVS functions, theorems, axioms, lemmas")
  491.  
  492. ;;; Tex, LaTex
  493. ;;;
  494. ;;; Philippe Queinnec <queinnec@cenatls.cena.dgac.fr>
  495. ;;; Paolo Frasconi <paolo@mcculloch.ing.unifi.it>
  496. (fume-defvar-local fume-tex-chapter 0)
  497. (fume-defvar-local fume-tex-section 0)
  498. (fume-defvar-local fume-tex-subsection 0)
  499. (fume-defvar-local fume-tex-subsubsection 0)
  500.  
  501. (defun fume-tex-rescan-buffer-hook ()
  502.   (setq fume-tex-chapter 0
  503.         fume-tex-section 0
  504.         fume-tex-subsection 0
  505.         fume-tex-subsubsection 0))
  506.  
  507. (defun fume-tweak-tex-mode ()
  508.   (setq fume-sort-function nil)
  509.   (add-hook 'fume-rescan-buffer-hook 'fume-tex-rescan-buffer-hook))
  510.  
  511. (add-hook 'tex-mode-hook 'fume-tweak-tex-mode)
  512. ;;; C. Michael Holloway <c.m.holloway@larc.nasa.gov>
  513. (add-hook 'TeX-mode-hook 'fume-tweak-tex-mode)
  514. ;;; Wolfgang Mettbach <wolle@uni-paderborn.de>
  515. (add-hook 'latex-mode-hook 'fume-tweak-tex-mode)
  516. (add-hook 'LaTeX-mode-hook 'fume-tweak-tex-mode)
  517.  
  518. ;;; Philippe Queinnec <queinnec@cenatls.cena.dgac.fr>
  519. (defconst fume-section-name-regexp-latex
  520.   (concat
  521.    "^\\s-*\\\\\\("
  522.    "\\(sub\\)*section\\|chapter\\)"
  523.    "\\*?\\(\\[[^]]*\\]\\)?{\\([^}]*\\)}"
  524.    )
  525.   "Expression to get latex section names")
  526.  
  527. ;;; ksh
  528. ;;;
  529. ;;; Philippe Bondono <bondono@vnet.ibm.com>
  530. (defconst fume-function-name-regexp-ksh
  531.   (concat
  532.    "\\(^\\s-*function\\s-+[A-Za-z_][A-Za-z_0-9]*\\)"
  533.    "\\|"
  534.    "\\(^\\s-*[A-Za-z_][A-Za-z_0-9]*\\s-*()\\)")
  535.   "Expression to get ksh function names")
  536.  
  537. ;;; Scheme
  538. ;;;
  539. ;;; C. Michael Holloway <c.m.holloway@larc.nasa.gov>
  540. (defconst fume-function-name-regexp-scheme
  541.   "^(define [ ]*"
  542.   "Expression to get Scheme function names")
  543.  
  544. ;;; BibTeX
  545. ;;;
  546. ;;; C. Michael Holloway <c.m.holloway@larc.nasa.gov>
  547. (defconst fume-function-name-regexp-bibtex
  548.   "^@[A-Za-z]*[({]\\([A-Za-z0-9:;&-]*\\),"
  549.   "Expression to get bibtex citation headers.")
  550.  
  551. ;;; SGML
  552. ;;;
  553. ;;; Thomas Plass <thomas.plass@mid-heidelberg.de>
  554. (defconst fume-function-name-regexp-sgml
  555.   "<!\\(element\\|entity\\)[ \t\n]+%?[ \t\n]*\\([A-Za-z][-A-Za-z.0-9]*\\)"
  556.   "Expression to find declaration of SGML element or entity")
  557.  
  558. ;;; Ada
  559. ;;;
  560. ;;; Michael Polo <mikep@polo.mn.org> <mikep@cfsmo.honeywell.com>
  561. (defconst fume-function-name-regexp-ada
  562.   (cons "^[ \t]*\\(procedure\\|PROCEDURE\\|function\\|FUNCTION\\)[ \n\t]+\\([a-zA-Z0-9_]+\\|\"[^\"]\"\\)" 2)
  563.   "Expression to find declaration of Ada function")
  564.  
  565. ;;; ignore prototypes, 'renames', 'is new' to eliminate clutter
  566. ;;;
  567. ;;; Scott Evans <gse@ocsystems.com>
  568. (defconst fume-function-name-regexp-ada-ignore
  569.   "[ \n\t]*\\(([^()]+)[ \n\t]*\\)?\\(return[ \t\n]+[^ \t\n;]+[ \n\t]*\\)?\\(;\\|is[ \n\t]+new[ \n\t]\\|renames\\)"
  570.   "ignore if ada function name matches this string")
  571.  
  572. ;;; Makefiles
  573. ;;;
  574. ;;; Paul Filipski & Anthony Girardin <{filipski,girardin}@blackhawk.com>
  575. (defconst fume-function-name-regexp-make
  576.   "^\\(\\(\\$\\s(\\)?\\(\\w\\|\\.\\)+\\(:sh\\)?\\(\\s)\\)?\\)\\s *\\(::?\\|\\+?=\\)"
  577.   "Expression to get makefile target names")
  578. (add-hook 'makefile-mode-hook 'fume-add-menubar-entry)
  579.  
  580. ;;; Directory Listings
  581. ;;;
  582. ;;; Norbert Kiesel <norbert@i3.informatik.rwth-aachen.de>
  583. ;;; regexp stolen from font-lock-mode
  584. (defconst fume-function-name-regexp-dired
  585.   "^. +d.*\\(Jan\\|Feb\\|Mar\\|Apr\\|May\\|Jun\\|Jul\\|Aug\\|Sep\\|Oct\\|Nov\\|Dec\\) +[0-9]+ +[0-9:]+ \\(.*\\)$"
  586.   "Expression to get directory names")
  587.  
  588. ;;; Pascal
  589. ;;;
  590. ;;; Espen Skoglund <espensk@stud.cs.uit.no>
  591. (defconst fume-function-name-regexp-pascal
  592.   "^\\(function\\|procedure\\)[ \t]+\\([_a-zA-Z][_a-zA-Z0-9]*\\)"
  593.   "Expression to get function/procedure names in pascal.")
  594.  
  595.  
  596. ;;; Fame
  597. ;;;
  598. ;;; Cooper Vertz <cooper@prod2.imsi.com>
  599. (defconst fume-function-name-regexp-fame
  600.   "^\\(function\\|procedure\\)[ \t]+\\([#\\$%_a-zA-Z][#\\$%_a-zA-Z0-9]*\\)"
  601.   "Expression to get function/procedure names in fame.")
  602.  
  603.  
  604. ;;; Verilog support
  605. ;;;
  606. ;;; Matt Sale <mdsale@icdc.delcoelect.com>
  607. (defconst fume-function-name-regexp-verilog
  608.   "^\\(task\\|function\\|module\\|primitive\\)[ \t]+\\([A-Za-z0-9_+-]*\\)[ \t]*(?"
  609.   "Expression to get verilog module names")
  610.  
  611.  
  612. ;;; Assembly
  613. (defconst fume-function-name-regexp-asm
  614. "^\\([a-zA-Z_.$][a-zA-Z0-9_.$]*\\)[ \t]*:"
  615.   "Expression to get assembly label names")
  616.  
  617. ;;; This is where the mode specific regexp's are hooked in
  618. ;;;
  619. (defconst fume-function-name-regexp-alist
  620.   '(;; Lisp
  621.     (lisp-mode             . fume-function-name-regexp-lisp)
  622.     (emacs-lisp-mode       . fume-function-name-regexp-lisp)
  623.     (lisp-interaction-mode . fume-function-name-regexp-lisp)
  624.  
  625.     ;; C
  626.     (c-mode      . fume-function-name-regexp-c)
  627.     (elec-c-mode . fume-function-name-regexp-c)
  628.     ;; Bob Weiner <weiner@mot.com>
  629.     (c++-c-mode  . fume-function-name-regexp-c)
  630.  
  631.     ;; C++
  632.     (c++-mode . fume-function-name-regexp-c++)
  633.  
  634.     ;; FORTRAN
  635.     ;; Paul Emsley <paule@chem.gla.ac.uk>
  636.     (fortran-mode . fume-function-name-regexp-fortran)
  637.  
  638.     ;; Modula
  639.     (modula-2-mode . fume-function-name-regexp-modula)
  640.     (modula-3-mode . fume-function-name-regexp-modula)
  641.  
  642.     ;; Bacis2
  643.     (bacis-mode . fume-function-name-regexp-bacis)
  644.  
  645.     ;; Maple
  646.     ;; Luc Tancredi <Luc.Tancredi@sophia.inria.fr>
  647.     (maple-mode . fume-function-name-regexp-maple)
  648.  
  649.     ;; Perl
  650.     (perl-mode . fume-function-name-regexp-perl)
  651.  
  652.     ;; Python
  653.     ;; Shuichi Koga <skoga@virginia.edu>
  654.     (alice-mode  . fume-function-name-regexp-python)
  655.     (python-mode . fume-function-name-regexp-python)
  656.  
  657.     ;; Postscript
  658.     ;; Leigh L. Klotz <klotz@adoc.xerox.com>
  659.     (postscript-mode . fume-function-name-regexp-postscript)
  660.  
  661.     ;; Prolog
  662.     ;; Laszlo Teleki <laszlo@ipb.uni-bonn.de>
  663.     (prolog-mode . fume-function-name-regexp-prolog)
  664.  
  665.     ;; Tcl
  666.     ;; Jean-Michel Augusto <augusto@eurecom.fr>
  667.     (tcl-mode . fume-function-name-regexp-tcl)
  668.  
  669.     ;; ksh
  670.     ;; Philippe Bondono <bondono@vnet.ibm.com>
  671.     (ksh-mode . fume-function-name-regexp-ksh)
  672.  
  673.     ;; LaTeX
  674.     ;; Philippe Queinnec <queinnec@cenatls.cena.dgac.fr>
  675.     (latex-mode . fume-section-name-regexp-latex)
  676.     (LaTeX-mode . fume-section-name-regexp-latex)
  677.  
  678.     ;; Scheme
  679.     ;; C. Michael Holloway <c.m.holloway@larc.nasa.gov>
  680.     (scheme-mode . fume-function-name-regexp-scheme)
  681.  
  682.     ;; BibTeX
  683.     ;; C. Michael Holloway <c.m.holloway@larc.nasa.gov>
  684.     (bibtex-mode . fume-function-name-regexp-bibtex)
  685.  
  686.     ;; Ehdm & PVS
  687.     ;; C. Michael Holloway <c.m.holloway@larc.nasa.gov>
  688.     (ehdm-mode . fume-function-name-regexp-ehdm)
  689.     (pvs-mode  . fume-function-name-regexp-pvs)
  690.  
  691.     ;; SGML
  692.     ;; Thomas Plass <thomas.plass@mid-heidelberg.de>
  693.     (sgml-mode . fume-function-name-regexp-sgml)
  694.  
  695.     ;; Ada
  696.     ;; Mike Polo <mikep@cfsmo.honeywell.com>, <mikep@polo.mn.org>
  697.     (ada-mode . fume-function-name-regexp-ada)
  698.  
  699.     ;; Makefiles
  700.     ;; Paul Filipski & Anthony Girardin <{filipski,girardin}@blackhawk.com>
  701.     (makefile-mode . fume-function-name-regexp-make)
  702.  
  703.     ;; Dired
  704.     ;; Norbert Kiesel <norbert@i3.informatik.rwth-aachen.de>
  705.     (dired-mode . fume-function-name-regexp-dired)
  706.  
  707.     ;; Pascal
  708.     ;; Espen Skoglund <espensk@stud.cs.uit.no>
  709.     (pascal-mode . fume-function-name-regexp-pascal)
  710.  
  711.     ;; Fame
  712.     ;; Cooper Vertz <cooper@prod2.imsi.com>
  713.     (fame-mode . fume-function-name-regexp-fame)
  714.  
  715.     ;; Verilog support
  716.     ;; Matt Sale <mdsale@icdc.delcoelect.com>
  717.     (verilog-mode . fume-function-name-regexp-verilog)
  718.  
  719.     ;; Assembly
  720.     ;; Bob Weiner <weiner@mot.com>
  721.     (asm-mode . fume-function-name-regexp-asm)
  722.     )
  723.  
  724.   "The connection between a mode and the regexp that matches function names.")
  725.  
  726. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  727. ;;;;;;;;;;;;;;;;;;;;;  Mode specific finding functions  ;;;;;;;;;;;;;;;;;;;;
  728. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  729.  
  730. ;;; Default routine : Note, most modes will need a specialised routine
  731. ;;;
  732. (defun fume-find-next-function-name (buffer)
  733.   "Searches for the next function in BUFFER."
  734.   (set-buffer buffer)
  735.   ;; Search for the function
  736.   (if (re-search-forward fume-function-name-regexp nil t)
  737.       (let ((char (progn
  738.                     (backward-up-list 1)
  739.                     (save-excursion
  740.                       (goto-char (scan-sexps (point) 1))
  741.                       (skip-chars-forward "[ \t\n]")
  742.                       (following-char)))))
  743.         ;; Skip this function name if it is a prototype declaration.
  744.         (if (and (eq char ?\;) (not (eq major-mode 'emacs-lisp-mode)))
  745.             (fume-find-next-function-name buffer)
  746.           ;; Get the function name and position
  747.           (let (beg)
  748.             (forward-sexp -1)
  749.             (setq beg (point))
  750.             (forward-sexp)
  751.             (cons (buffer-substring beg (point)) beg))))))
  752.  
  753. ;;; General purpose sexp find function
  754. ;;;
  755. (defun fume-find-next-sexp (buffer)
  756.   "Searches for the next sexp type function in BUFFER."
  757.   (set-buffer buffer)
  758.   (if (re-search-forward fume-function-name-regexp nil t)
  759.       (let ((beg (save-excursion (forward-sexp -1) (point))))
  760.         (cons (buffer-substring beg (point)) beg))))
  761.  
  762. ;;; Specialised routine to get the next ehdm entity in the buffer.
  763. ;;; C. Michael Holloway <c.m.holloway@larc.nasa.gov>
  764. ;;;
  765. (defun fume-find-next-ehdm-entity (buffer)
  766.   (set-buffer buffer)
  767.   (if (re-search-forward fume-function-name-regexp nil t)
  768.       (let ((beg (match-beginning 0))
  769.             (end (match-end 0)))
  770.         (cons (buffer-substring beg end) beg))))
  771.  
  772. ;;; Specialised routine to get the next PVS entity in the buffer.
  773. ;;; C. Michael Holloway <c.m.holloway@larc.nasa.gov>
  774. ;;;
  775. (defun fume-find-next-pvs-entity (buffer)
  776.   (set-buffer buffer)
  777.   (if (re-search-forward fume-function-name-regexp nil t)
  778.       (let ((beg (match-beginning 0))
  779.             (end (match-end 0)))
  780.         (goto-char (1- end))
  781.         (if (looking-at ":")
  782.             (setq end (1- end)))
  783.         (cons (buffer-substring beg end) beg))))
  784.  
  785. ;;; Specialised routine to get the next C function name in the buffer.
  786. ;;;
  787. (defun fume-find-next-c-function-name (buffer)
  788.   "Searches for the next C function in BUFFER."
  789.   (set-buffer buffer)
  790.   ;; Search for the function
  791.   (if (re-search-forward fume-function-name-regexp nil t)
  792.       (let ((char (progn
  793.                     (backward-up-list 1)
  794.                     (save-excursion
  795.                       (goto-char (scan-sexps (point) 1))
  796.                       (skip-chars-forward "[ \t\n]")
  797.                       (following-char)))))
  798.         ;; Skip this function name if it is a prototype declaration.
  799.         (if (eq char ?\;)
  800.             (fume-find-next-function-name buffer)
  801.           (let (beg
  802.                 name)
  803.             ;; Get the function name and position
  804.             (forward-sexp -1)
  805.             (setq beg (point))
  806.             (forward-sexp)
  807.             (setq name (buffer-substring beg (point)))
  808.             ;; ghastly crock for DEFUN declarations
  809.             (cond ((string-match "^DEFUN\\s-*" name)
  810.                    (forward-word 1)
  811.                    (forward-word -1)
  812.                    (setq beg (point))
  813.                    (cond ((re-search-forward "\"," nil t)
  814.                           (re-search-backward "\"," nil t)
  815.                           (setq name
  816.                                 (format "%s %s"
  817.                                         name
  818.                                         (buffer-substring beg (point))))))))
  819.             ;; kludge to avoid 'void' in menu
  820.             (if (string-match "^void\\s-*" name)
  821.                 (fume-find-next-function-name buffer)
  822.               (cons name beg)))))))
  823.  
  824. ;;; <jrm@odi.com>
  825. ;;; <ajp@eng.cam.ac.uk>
  826. ;;; <schittko@fokus.gmd.de>
  827. ;;;
  828. (defun fume-match-find-next-function-name (buffer)
  829.   "General next function name in BUFFER finder using match.
  830. The regexp is assumed to be a two item list the car of which is the regexp to
  831. use, and the cdr of which is the match position of the function name."
  832.   (set-buffer buffer)
  833.   (let ((result nil)
  834.         (continue t))
  835.     (while continue
  836.       ;; Search for the function
  837.       (if (re-search-forward (car fume-function-name-regexp) nil t)
  838.           (let ((char (progn
  839.                         (backward-up-list 1)
  840.                         (save-excursion
  841.                           (goto-char (scan-sexps (point) 1))
  842.                           (following-char)))))
  843.             ;; Skip this function name if it is a prototype declaration.
  844.             (if (eq char ?\;)
  845.                 nil
  846.               (setq result
  847.                     ;; Get the function name and position including scope
  848.                     (cons (buffer-substring
  849.                            (match-beginning (cdr fume-function-name-regexp))
  850.                            (point))
  851.                           (match-beginning (cdr fume-function-name-regexp)))
  852.                     continue nil)))
  853.         (setq continue nil)))
  854.     result))
  855.  
  856. ;;; Specialised routine to find the next Perl function
  857. ;;;
  858. (defun fume-find-next-perl-function-name (buffer)
  859.   "Searches for the next Perl function in BUFFER."
  860.   (fume-find-next-sexp buffer))
  861.  
  862. ;;; Specialised routine to find the next Python function
  863. ;;; Shuichi Koga <skoga@virginia.edu>
  864. ;;;
  865. (defun fume-find-next-python-function-name (buffer)
  866.   "Searches for the next python function in BUFFER."
  867.   (set-buffer buffer)
  868.   (if (re-search-forward fume-function-name-regexp nil t)
  869.       (save-excursion
  870.         (let* ((retpnt (match-beginning 2))
  871.                (retname (buffer-substring retpnt (match-end 2))))
  872.           (goto-char (match-beginning 0))
  873.           (cond ((looking-at "\\s-+def")
  874.                  (re-search-backward
  875.                   "^class\\s-*\\([A-Za-z0-9_]+\\)\\s-*[(:]" nil t)
  876.                  (setq retname
  877.                        (concat
  878.                         (buffer-substring (match-beginning 1) (match-end 1))
  879.                         "."
  880.                         retname))))
  881.           (cons retname retpnt)))))
  882.  
  883. ;;; Specialised routine to find the next Modula function or subroutine.
  884. ;;;
  885. (defun fume-find-next-modula-function-name (buffer)
  886.   "Searches for the next modula function in BUFFER."
  887.   (fume-find-next-sexp buffer))
  888.  
  889. ;;; Specialised routine to find the next directory.
  890. ;;; Norbert Kiesel <norbert@i3.informatik.rwth-aachen.de>
  891. ;;;
  892. (defun fume-find-next-directory-name (buffer)
  893.   "Searches for the next directory in dired BUFFER."
  894.   (set-buffer buffer)
  895.   ;; Search for the function
  896.   (if (re-search-forward fume-function-name-regexp nil t)
  897.       (let ((beg (match-beginning 2))
  898.             (end (match-end 2)))
  899.         (cons (buffer-substring beg end) beg))))
  900.  
  901. ;;; Specialised routine to find the next FORTRAN function or subroutine
  902. ;;;
  903. (defun fume-find-next-fortran-function-name (buffer)
  904.   "Searches for the next fortran function in BUFFER."
  905.   (set-buffer buffer)
  906.   (if (re-search-forward fume-function-name-regexp nil t)
  907.       (let ((pos (point))
  908.             ;; name may have "_" but must start with a letter
  909.             (name-regexp "\\s-+[a-zA-Z]+[_a-zA-Z0-9*]*")
  910.             (eol (save-excursion (end-of-line 1) (point))))
  911.         (skip-chars-backward " \t")
  912.         (if (re-search-forward name-regexp eol t)
  913.             ;; name is ok; so return it
  914.             (cons (buffer-substring pos (point)) pos)
  915.           ;; rubbish found; skip to next function
  916.           (fume-find-next-fortran-function-name buffer)))))
  917.  
  918. ;;; Specialised routine to get the next postscript function name in the buffer
  919. ;;; Leigh L. Klotz <klotz@adoc.xerox.com>
  920. ;;;
  921. (defun fume-find-next-postscript-function-name (buffer)
  922.   "Searches for the next postscript function in BUFFER."
  923.   (set-buffer buffer)
  924.   (if (re-search-forward fume-function-name-regexp nil t)
  925.       (let ((beg (progn (beginning-of-line 1) (point))))
  926.         (forward-sexp)
  927.         ;; keep including sexps as long as they
  928.         ;; start with / or [.
  929.         (if (looking-at "\\s-+\\(/\\|\\[\\)")
  930.             (forward-sexp))
  931.         (cons (buffer-substring beg (point)) beg))))
  932.  
  933. ;;; Specialised routine to get the next prolog fact/clause name in the buffer
  934. ;;; Laszlo Teleki <laszlo@ipb.uni-bonn.de>
  935. ;;;
  936. (defun fume-find-next-prolog-function-name (buffer)
  937.   "Searches for the next prolog fact or clause in BUFFER."
  938.   (set-buffer buffer)
  939.   (if (re-search-forward fume-function-name-regexp nil t)
  940.       (let ((beg (progn (beginning-of-line 1) (point))))
  941.         (forward-sexp)
  942.         (cons (buffer-substring beg (point)) beg))))
  943.  
  944. ;;; Specialised routine to get the next bacis2 procedure name in the buffer
  945. ;;;
  946. (defun fume-find-next-bacis-function-name (buffer)
  947.   "Searches for the next Bacis2 function in BUFFER"
  948.   (set-buffer buffer)
  949.   (if (re-search-forward fume-function-name-regexp nil t)
  950.       (let ((pos (point))
  951.             (name (condition-case ()
  952.                       (funcall
  953.                        (symbol-function (intern "focus-get-function-name")))
  954.                     (error nil))))
  955.         (if (null name)
  956.             (fume-find-next-bacis-function-name buffer)
  957.           ;; jump past possible function dbgid
  958.           (re-search-forward
  959.            (format "<<dbgid +\\s-*%s%s" name "\\s-*>>") nil t)
  960.           (cons name pos)))))
  961.  
  962. ;;; Specialized routine to get the next Maple function name in the buffer
  963. ;;; Luc Tancredi <Luc.Tancredi@sophia.inria.fr>
  964. ;;;
  965. (defun fume-find-next-maple-function-name (buffer)
  966.   "Searches for the next maple function in BUFFER"
  967.   (set-buffer buffer)
  968.   ;; Search for the function
  969.   (if (re-search-forward fume-function-name-regexp nil t)
  970.       (let ((beg (progn (backward-up-list 1) (forward-sexp -2) (point))))
  971.         (forward-sexp)
  972.         (cons (buffer-substring beg (point)) beg))))
  973.  
  974. ;;; Specialised routine to get the next latex section name in the buffer
  975. ;;; Philippe Queinnec <queinnec@cenatls.cena.dgac.fr>
  976. ;;; Paolo Frasconi <paolo@mcculloch.ing.unifi.it>
  977. ;;;
  978. (defun fume-find-next-latex-section-name (buffer)
  979.   "Searches for the next latex section in BUFFER."
  980.   (set-buffer buffer)
  981.   (if (re-search-forward fume-function-name-regexp nil t)
  982.       (let* ((secname (buffer-substring (match-beginning 1) (match-end 1)))
  983.              (beg (match-beginning 4))
  984.              (name (buffer-substring beg (match-end 4))))
  985.         (cond ((string= secname "chapter")
  986.                (setq fume-tex-chapter (1+ fume-tex-chapter)
  987.                      fume-tex-section 0
  988.                      fume-tex-subsection 0
  989.                      fume-tex-subsubsection 0
  990.                      name (concat fume-tex-chapter " " (upcase name))))
  991.               ((string= secname "section")
  992.                (setq fume-tex-section (1+ fume-tex-section)
  993.                      name (concat
  994.                            (if (> fume-tex-chapter 0)
  995.                                (concat fume-tex-chapter ".") "")
  996.                            fume-tex-section " " name)
  997.                      fume-tex-subsection 0
  998.                      fume-tex-subsubsection 0))
  999.               ((string= secname "subsection")
  1000.                (setq fume-tex-subsection (1+ fume-tex-subsection)
  1001.                      name (concat
  1002.                            (if (> fume-tex-chapter 0)
  1003.                                (concat fume-tex-chapter ".") "")
  1004.                            fume-tex-section "."
  1005.                            fume-tex-subsection " " name)
  1006.                      fume-tex-subsubsection 0))
  1007.               ((string= secname "subsubsection")
  1008.                (setq fume-tex-subsubsection (1+ fume-tex-subsubsection)
  1009.                      name (concat
  1010.                            (if (> fume-tex-chapter 0)
  1011.                                (concat fume-tex-chapter ".") "")
  1012.                            fume-tex-section "."
  1013.                            fume-tex-subsection "."
  1014.                            fume-tex-subsubsection " " name)))
  1015.               ((string= secname "subsubsection")
  1016.                (setq name (concat "   " name))))
  1017.         (cons name beg))))
  1018.  
  1019. ;;; Specialised routine to get the next ksh function in the buffer
  1020. ;;; Philippe Bondono <bondono@vnet.ibm.com>
  1021. ;;;
  1022. (defun fume-find-next-ksh-function-name (buffer)
  1023.   "Searches for the ksh type function in BUFFER."
  1024.   (set-buffer buffer)
  1025.   ;; Search for the function
  1026.   (if (re-search-forward fume-function-name-regexp nil t)
  1027.       (let (name
  1028.             (beg (match-beginning 0)))
  1029.         (cond ((re-search-backward "\\(^\\|\\s-\\)function\\s-" beg t)
  1030.                (re-search-forward
  1031.                 "\\(function\\s-+\\)\\([A-Za-z_][A-Za-z_0-9]*\\)" nil t)
  1032.                (setq beg (match-beginning 2)
  1033.                      name (buffer-substring beg (match-end 2))))
  1034.               (t
  1035.                (re-search-backward
  1036.                 "\\(^\\|\\s-\\)\\([A-Za-z_][A-Za-z_0-9]*\\)" beg t)
  1037.                (setq beg (match-beginning 2)
  1038.                      name (buffer-substring beg (match-end 2)))))
  1039.         (if (null name)
  1040.             (fume-find-next-ksh-function-name buffer)
  1041.           (end-of-line)
  1042.           (cons name beg)))))
  1043.  
  1044. ;;; Specialised routine to get the next Scheme function in the buffer
  1045. ;;; C. Michael Holloway <c.m.holloway@larc.nasa.gov>
  1046. ;;;
  1047. (defun fume-find-next-scheme-function (buffer)
  1048.   "Searches for the next Scheme function in BUFFER."
  1049.   (set-buffer buffer)
  1050.   (if (re-search-forward fume-function-name-regexp nil t)
  1051.       (let ((beg (progn (if (looking-at "(") (forward-char 1)) (point)))
  1052.             (end (save-excursion (forward-sexp) (point))))
  1053.         (cons (buffer-substring beg end) beg))))
  1054.  
  1055. ;;; Specialised routine to get the next BibTeX citation in the buffer
  1056. ;;; C. Michael Holloway <c.m.holloway@larc.nasa.gov>
  1057. ;;;
  1058. (defun fume-find-next-bibtex-citation (buffer)
  1059.   "Searches for the next BibTeX citation in BUFFER."
  1060.   (set-buffer buffer)
  1061.   (if (re-search-forward fume-function-name-regexp nil t)
  1062.       (let ((beg (match-beginning 1))
  1063.             (end (match-end 1)))
  1064.         (cons (buffer-substring beg end) beg))))
  1065.  
  1066. ;;; Specialised routine to get the next SGML declaration in the buffer
  1067. ;;; Thomas Plass <thomas.plass@mid-heidelberg.de>
  1068. ;;;
  1069. (defun fume-find-next-sgml-element-name (buffer)
  1070.   "Searches for the next SGML declaration in BUFFER."
  1071.   (set-buffer buffer)
  1072.   (if (re-search-forward fume-function-name-regexp nil t)
  1073.       (let ((type (buffer-substring (match-beginning 1) (match-end 1)))
  1074.             (beg (match-beginning 2))
  1075.             (name (buffer-substring (match-beginning 2) (match-end 2))))
  1076.         (if (string= (downcase type) "element")
  1077.             (setq name (format "%-17s%3s" name "EL"))
  1078.           (setq name (format "%-17s%3s" name "ENT")))
  1079.         (cons name beg))))
  1080.  
  1081. ;;; Specialised routine to get the next ada function in the buffer
  1082. ;;; Michael Polo <mikep@polo.mn.org> <mikep@cfsmo.honeywell.com>
  1083. ;;;
  1084. (defun fume-find-next-ada-function-name (buffer)
  1085.   "Searches for the next ada function in BUFFER."
  1086.   (set-buffer buffer)
  1087.   (if (re-search-forward (car fume-function-name-regexp-ada) nil t)
  1088.       (let ((beg (match-beginning (cdr fume-function-name-regexp-ada)))
  1089.             (end (match-end (cdr fume-function-name-regexp-ada))))
  1090.  
  1091.         (if (looking-at fume-function-name-regexp-ada-ignore)
  1092.             (fume-find-next-ada-function-name buffer)
  1093.           (cons (buffer-substring beg end) beg)))))
  1094.  
  1095. ;;; Makefiles
  1096. ;;; Paul Filipski & Anthony Girardin <{filipski,girardin}@blackhawk.com>
  1097. ;;;
  1098. (defun fume-find-next-function-name-make (buffer)
  1099.   "Searches for the next make item in BUFFER."
  1100.   (set-buffer buffer)
  1101.   (if (re-search-forward fume-function-name-regexp nil t)
  1102.       (let ((beg (match-beginning 1))
  1103.             (end (match-end 1)))
  1104.         (cons (buffer-substring beg end) beg))))
  1105.  
  1106. ;;; Find next pascal function in the buffer
  1107. ;;; Espen Skoglund <espensk@stud.cs.uit.no>
  1108. ;;;
  1109. (defun fume-find-next-pascal-function-name (buffer)
  1110.   "Searches for the next pascal procedure in BUFFER."
  1111.   (set-buffer buffer)
  1112.   (if (re-search-forward fume-function-name-regexp nil t)
  1113.       (let ((beg (match-beginning 2))
  1114.             (end (match-end 2)))
  1115.         (cons (buffer-substring beg end) beg))))
  1116.  
  1117. ;;; Verilog support
  1118. ;;; Matt Sale <mdsale@icdc.delcoelect.com>
  1119. ;;;
  1120. (defun fume-find-next-verilog-function-name (buffer)
  1121.   "Searches for the next verilog module in BUFFER."
  1122.   (set-buffer buffer)
  1123.   (if (re-search-forward fume-function-name-regexp nil t)
  1124.       (let ((beg (match-beginning 2))
  1125.             (end (match-end 2)))
  1126.         (cons (buffer-substring beg end) beg))))
  1127.  
  1128. ;;; Assembly support
  1129. ;;; Bob Weiner <weiner@mot.com>
  1130. ;;;
  1131. (defun fume-find-next-asm-function-name (buffer)
  1132.   "Searches for the next assembler function in BUFFER."
  1133.   (set-buffer buffer)
  1134.   ;; Search for the function
  1135.   (if (re-search-forward fume-function-name-regexp nil t)
  1136.       (cons (buffer-substring (match-beginning 1) (match-end 1))
  1137.             (match-beginning 1))))
  1138.  
  1139. ;;; This is where you can hook in other languages which may need a different
  1140. ;;; method to scan for function names. Otherwise, the default defun used is
  1141. ;;; fume-find-next-function-name which is suitable for sexp-based languages
  1142. ;;; such as C, C++ and elisp.
  1143. ;;;
  1144. (defconst fume-find-function-name-method-alist
  1145.   '((ada-mode        . fume-find-next-ada-function-name)
  1146.     (alice-mode      . fume-find-next-python-function-name)
  1147.     (asm-mode        . fume-find-next-asm-function-name)
  1148.     (bacis-mode      . fume-find-next-bacis-function-name)
  1149.     (bibtex-mode     . fume-find-next-bibtex-citation)
  1150.     (c++-mode        . fume-match-find-next-function-name)
  1151.     (c-mode          . fume-find-next-c-function-name)
  1152.     (dired-mode      . fume-find-next-directory-name)
  1153.     (ehdm-mode       . fume-find-next-ehdm-entity)
  1154.     (fame-mode       . fume-find-next-pascal-function-name)
  1155.     (fortran-mode    . fume-find-next-fortran-function-name)
  1156.     (ksh-mode        . fume-find-next-ksh-function-name)
  1157.     (latex-mode      . fume-find-next-latex-section-name)
  1158.     (LaTeX-mode      . fume-find-next-latex-section-name)
  1159.     (makefile-mode   . fume-find-next-function-name-make)
  1160.     (maple-mode      . fume-find-next-maple-function-name)
  1161.     (modula-2-mode   . fume-find-next-modula-function-name)
  1162.     (modula-3-mode   . fume-find-next-modula-function-name)
  1163.     (pascal-mode     . fume-find-next-pascal-function-name)
  1164.     (perl-mode       . fume-find-next-perl-function-name)
  1165.     (postscript-mode . fume-find-next-postscript-function-name)
  1166.     (prolog-mode .     fume-find-next-prolog-function-name)
  1167.     (pvs-mode        . fume-find-next-pvs-entity)
  1168.     (python-mode     . fume-find-next-python-function-name)
  1169.     (scheme-mode     . fume-find-next-scheme-function)
  1170.     (sgml-mode       . fume-find-next-sgml-element-name)
  1171.     (tcl-mode        . fume-match-find-next-function-name)
  1172.     (verilog-mode    . fume-find-next-verilog-function-name)
  1173.     )
  1174.  
  1175.   "The connection between a mode and the defun that finds function names.
  1176. If no connection is in this alist for a given mode, a default method is used")
  1177.  
  1178. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1179. ;;;;;;;;;;;;;;;;;;;;;;;;  General utility functions  ;;;;;;;;;;;;;;;;;;;;;;;
  1180. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1181.  
  1182. ;;; Routine to refresh the modeline
  1183. ;;;
  1184. (if (fboundp 'redraw-modeline)          ; faster built-in method
  1185.     (defalias 'fume-refresh-modeline 'redraw-modeline)
  1186.   (defun fume-refresh-modeline ()       ; use old kludge method
  1187.     (set-buffer-modified-p (buffer-modified-p))))
  1188.  
  1189. ;;; Sets 'fume-function-name-regexp' to something appropriate for the current
  1190. ;;; mode for this buffer.
  1191. ;;;
  1192. (defun fume-set-defaults ()
  1193.   "Returns nil if unsuccessful in setting up buffer-local defaults.
  1194. Otherwise returns fume-function-name-regexp"
  1195.   (setq fume-function-name-regexp
  1196.         (symbol-value
  1197.          (cdr-safe (assoc major-mode fume-function-name-regexp-alist))))
  1198.   (if fume-function-name-regexp
  1199.       (setq fume-find-next-function-name-method
  1200.             (or (cdr-safe (assoc major-mode
  1201.                                  fume-find-function-name-method-alist))
  1202.                 'fume-find-next-function-name)))
  1203.   fume-function-name-regexp)
  1204.  
  1205. ;;; Routines to add/remove/update function menu from menubar
  1206. ;;;
  1207. (defsubst fume-add-menubar-entry ()
  1208.   (interactive)
  1209.   (save-window-excursion (function-menu t)))
  1210.  
  1211. (defsubst fume-remove-menubar-entry ()
  1212.   (interactive)
  1213.   (cond ((and fume-running-xemacs current-menubar)
  1214.          (delete-menu-item (list fume-menubar-menu-name))
  1215.          ;; force update of the menubar
  1216.          (fume-refresh-modeline))))
  1217.  
  1218. (defsubst fume-update-menubar-entry ()
  1219.   "Returns t if menubar was updated. Nil otherwise"
  1220.   (and fume-running-xemacs
  1221.        (assoc fume-menubar-menu-name current-menubar)
  1222.        (fume-add-menubar-entry)
  1223.        t))
  1224.  
  1225. (defsubst fume-trim-string (string)
  1226.   "Returns STRING with leading and trailing whitespace removed."
  1227.   (if (string-match "^[ \t]*" string)
  1228.       (setq string (substring string (match-end 0))))
  1229.   (if (string-match "[ \t]*$" string)
  1230.       (setq string (substring string 0 (match-beginning 0))))
  1231.   string)
  1232.  
  1233. (defvar fume-syntax-table nil)
  1234.  
  1235. (defsubst fume-what-looking-at ()
  1236.   (let (name
  1237.         (orig-syntax-table (copy-syntax-table (syntax-table))))
  1238.     (if fume-syntax-table
  1239.         ()
  1240.       (setq fume-syntax-table (copy-syntax-table))
  1241.       (modify-syntax-entry ?: "w" fume-syntax-table))
  1242.     (unwind-protect
  1243.         (progn
  1244.           (set-syntax-table fume-syntax-table)
  1245.           (save-excursion
  1246.            (while (looking-at "\\sw\\|\\s_") (forward-char 1))
  1247.            (if (re-search-backward "\\sw\\|\\s_" nil t)
  1248.                (let ((beg (progn (forward-char 1) (point))))
  1249.                  (forward-sexp -1)
  1250.                  (while (looking-at "\\s'") (forward-char 1))
  1251.                  (setq name (buffer-substring beg (point)))))))
  1252.       (set-syntax-table orig-syntax-table)
  1253.       name)))
  1254.  
  1255. ;;; Find function name that point is in.
  1256. ;;; The trick is to start from the end...
  1257. ;;;
  1258. (defsubst fume-function-before-point ()
  1259.   (if (or fume-modeline-funclist (fume-rescan-buffer) fume-modeline-funclist)
  1260.       (let (result
  1261.             (pt (point)))
  1262.         (save-excursion
  1263.           (catch 'found
  1264.             (mapcar (function
  1265.                      (lambda (p)
  1266.                        (goto-char (cdr p))
  1267.                        (beginning-of-line 1)
  1268.                        (if (>= pt (point))
  1269.                            (throw 'found (setq result (car p))))))
  1270.                     fume-modeline-funclist))
  1271.           result))))
  1272.  
  1273. ;;; Routine to install the modeline feature
  1274. ;;;
  1275. (defsubst fume-maybe-install-modeline-feature ()
  1276.   (cond ((fume-set-defaults)
  1277.          (or fume-modeline-funclist
  1278.              (memq 'fume-tickle-modeline post-command-hook)
  1279.              (fume-rescan-buffer))
  1280.          (make-variable-buffer-local 'post-command-hook)
  1281.          (add-hook 'post-command-hook 'fume-tickle-modeline)
  1282.          (fume-tickle-modeline-1)
  1283.          (fume-tickle-modeline)
  1284.          t                              ; return success flag
  1285.          )))
  1286.  
  1287. ;;; Routine to display function before point in the modeline
  1288. ;;;
  1289. (defun fume-tickle-modeline ()
  1290.   (let (fname (fume-display-in-modeline-p fume-display-in-modeline-p))
  1291.     (setq fname (and fume-display-in-modeline-p (fume-function-before-point))
  1292.           fume-display-in-modeline-p (not (null fname))
  1293.           mode-line-buffer-identification
  1294.           (if fume-display-in-modeline-p
  1295.               (list
  1296.                fume-modeline-buffer-identification-1
  1297.                (concat " `" (fume-trim-string (format "%s" fname)) "'"))
  1298.             fume-modeline-buffer-identification-0)))
  1299.   ;; force an update of the mode line
  1300.   (fume-refresh-modeline))
  1301.  
  1302. (fume-defvar-local fume-modeline-buffer-identification-0 nil
  1303.   "Storage for original modeline-buffer-identification")
  1304.  
  1305. (fume-defvar-local fume-modeline-buffer-identification-1 nil
  1306.   "Storage for munged modeline-buffer-identification")
  1307.  
  1308. (defun fume-tickle-modeline-1 ()
  1309.   (or fume-modeline-buffer-identification-0
  1310.       (setq fume-modeline-buffer-identification-0
  1311.             mode-line-buffer-identification))
  1312.   (setq fume-modeline-buffer-identification-1
  1313.         (let (newSeq)
  1314.           (mapcar
  1315.            (function
  1316.             (lambda (oldSeq)
  1317.               (or (and (stringp oldSeq)
  1318.                        (string-match "%[0-9]*f" oldSeq)
  1319.                        (aset
  1320.                         (setq newSeq (copy-sequence oldSeq))
  1321.                         (1- (match-end 0))
  1322.                         (string-to-char "b"))
  1323.                        newSeq)
  1324.                   oldSeq)))
  1325.            fume-modeline-buffer-identification-0))))
  1326.  
  1327. ;;; Routine to create a shallow separate copy of a list
  1328. ;;;
  1329. (if (fboundp 'copy-tree)                ; not built-in in all emacsen
  1330.     (defalias 'fume-shallow-copy-list 'copy-tree)
  1331.   (defun fume-shallow-copy-list (list)
  1332.     (mapcar (function (lambda (i) (cons (car i) (cdr i)))) list)))
  1333.  
  1334. ;;; Sort function to sort items depending on their function-name
  1335. ;;; An item looks like (NAME . POSITION).
  1336. ;;;
  1337. (defsubst fume-sort-by-name (item1 item2)
  1338.   (or (string-lessp (car item1) (car item2))
  1339.       (string-equal (car item1) (car item2))))
  1340.  
  1341. ;;; Sort function to sort items depending on their position
  1342. ;;;
  1343. (defsubst fume-sort-by-position (item1 item2)
  1344.   (<= (cdr item1) (cdr item2)))
  1345.  
  1346. ;;; Support function to calculate relative position in buffer
  1347. ;;;
  1348. (defsubst fume-relative-position ()
  1349.   (let ((pos (point))
  1350.         (total (buffer-size)))
  1351.     (if (> total 50000)
  1352.         ;; Avoid overflow from multiplying by 100!
  1353.         (/ (1- pos) (max (/ total 100) 1))
  1354.       (/ (* 100 (1- pos))
  1355.          (max total 1)))))
  1356.  
  1357. ;;; Split LIST into sublists of max length N
  1358. ;;; Example (fume-split '(1 2 3 4 5 6 7 8) 3)-> '((1 2 3) (4 5 6) (7 8))
  1359. ;;;
  1360. (defsubst fume-split (list n)
  1361.   (let ((i 0)
  1362.         result
  1363.         sublist
  1364.         (remain list))
  1365.     (while remain
  1366.       (if (= n (setq sublist (cons (car remain) sublist)
  1367.                      remain (cdr remain)
  1368.                      i (1+ i)))
  1369.           ;; We have finished a sublist
  1370.           (setq result (cons (nreverse sublist) result)
  1371.                 sublist nil
  1372.                 i 0)))
  1373.     ;; There might be a sublist (if the length of LIST mod n is != 0)
  1374.     ;; that has to be added to the result list.
  1375.     (if sublist
  1376.         (setq result (cons (nreverse sublist) result)))
  1377.     (nreverse result)))
  1378.  
  1379. ;;; Routines to create indexes for submenus
  1380. ;;;
  1381.  
  1382. ;;; Method 0
  1383. ;;;
  1384. (defun fume-index-sublist-method-0 (sublist count)
  1385.   (concat "Function sublist #" count))
  1386.  
  1387. ;;; Method 1
  1388. ;;; Thomas Plass <thomas.plass@mid-heidelberg.de>
  1389. ;;;
  1390. (defun fume-index-sublist-method-1 (sublist &rest count)
  1391.   (interactive)
  1392.   (let ((s (substring (car (car sublist)) 0 1))
  1393.         (e (substring (car (nth (1- (length sublist)) sublist)) 0 1)))
  1394.     (format "Function sublist (%s%s)"
  1395.             s (if (string-equal s e) "<>" (format "<>-%s<>" e)))))
  1396.  
  1397. ;;; Method 2
  1398. ;;; Paul Filipski & Anthony Girardin <{filipski,girardin}@blackhawk.com>
  1399. ;;;
  1400. (defun fume-index-sublist-method-2 (sublist &rest count)
  1401.   (let ((s (substring (car (car sublist))
  1402.                       0
  1403.                       (min (length (car (car sublist))) 10)))
  1404.         (e (substring (car (nth (1- (length sublist)) sublist))
  1405.                       0
  1406.                       (min (length (car (nth (1- (length sublist)) sublist)))
  1407.                            10))))
  1408.     (format "%s%s" s (if (string-equal s e) "<>" (format "<> ... %s<>" e)))))
  1409.  
  1410. ;;; Method 3
  1411. ;;;
  1412. (defun fume-index-sublist-method-3-1 (sublist ix limit)
  1413.   (let ((s1 (substring (car (car sublist)) 0 (min limit ix)))
  1414.         (s2 (substring
  1415.              (car (nth (1- (length sublist)) sublist))
  1416.              0 (min (length (car (nth (1- (length sublist)) sublist))) ix))))
  1417.     (cons s1 s2)))
  1418.  
  1419. (defun fume-index-sublist-method-3 (sublist &rest count)
  1420.   (let* ((cmplength 10)
  1421.          (limit (length (car (car sublist))))
  1422.          (result (fume-index-sublist-method-3-1 sublist cmplength limit))
  1423.          (str1 (car result))
  1424.          (str2 (cdr result)))
  1425.     (while (and (string-equal str1 str2) (< cmplength limit))
  1426.       (setq cmplength (1+ cmplength)
  1427.             result (fume-index-sublist-method-3-1 sublist cmplength limit)
  1428.             str1 (car result)
  1429.             str2 (cdr result)))
  1430.     (cond ((not (string-equal str1 str2))
  1431.            (format "%s<> ... %s<>" str1 str2))
  1432.           ((< cmplength limit)
  1433.            (format "%s<>" str1))
  1434.           (t
  1435.            (format "%s ..." str1)))))
  1436.  
  1437. ;;; Buffer rescanning
  1438. ;;;
  1439. (defun fume-rescan-buffer-trigger ()
  1440.   "Automatically spots when a buffer rescan becomes necessary"
  1441.   (if (> fume-rescan-trigger-counter 0)
  1442.       (setq fume-rescan-trigger-counter (1- fume-rescan-trigger-counter))
  1443.     (setq fume-rescan-trigger-counter
  1444.           (/ (buffer-size) fume-rescan-trigger-counter-buffer-size))
  1445.     (if (or fume-funclist-dirty-p
  1446.             (save-excursion
  1447.               (let (find fnam)
  1448.                 (condition-case ()
  1449.                     (and fume-function-name-regexp
  1450.                          (setq fnam (fume-function-before-point))
  1451.                          (setq find (symbol-value
  1452.                                      'fume-find-next-function-name-method))
  1453.                          (progn (end-of-line 1)
  1454.                                 (re-search-backward
  1455.                                  fume-function-name-regexp nil t))
  1456.                          (not (string-equal
  1457.                                fnam
  1458.                                (car (funcall find (current-buffer))))))
  1459.                   (error nil)))))
  1460.         (let ((fume-scanning-message nil))
  1461.           (fume-rescan-buffer)))))
  1462.  
  1463. (defsubst fume-install-rescan-buffer-trigger ()
  1464.   (cond ((null (memq 'fume-rescan-buffer-trigger post-command-hook))
  1465.          (make-variable-buffer-local 'post-command-hook)
  1466.          (add-hook 'post-command-hook 'fume-rescan-buffer-trigger 'append)
  1467.          ;; Make narrow-to-region tickle func-menu
  1468.          (or (fboundp 'fume-narrow-to-region)
  1469.              (fset 'fume-narrow-to-region
  1470.                    (symbol-function 'narrow-to-region)))
  1471.          (defun narrow-to-region (b e)
  1472.            "Restrict editing in this buffer to the current region.
  1473. The rest of the text becomes temporarily invisible and untouchable
  1474. but is not deleted; if you save the buffer in a file, the invisible
  1475. text is included in the file.  C-x n w makes all visible again.
  1476. See also `save-restriction'.
  1477.  
  1478. When calling from a program, pass two arguments; positions (integers
  1479. or markers) bounding the text that should remain visible"
  1480.            (interactive "r")
  1481.            (fume-narrow-to-region b e)
  1482.            (if fume-funclist (setq fume-funclist-dirty-p t)))
  1483.          ;; Make widen tickle func-menu
  1484.          (or (fboundp 'fume-widen)
  1485.              (fset 'fume-widen (symbol-function 'widen)))
  1486.          (defun widen ()
  1487.            "Remove restrictions (narrowing) from current buffer.
  1488. This allows the buffer's full text to be seen and edited."
  1489.            (interactive)
  1490.            (fume-widen)
  1491.            (if fume-funclist (setq fume-funclist-dirty-p t))))))
  1492.  
  1493. (defun fume-rescan-buffer (&optional popmenu)
  1494.   "Rescans the buffer for function names.
  1495. If optional arg POPMENU is non-nil, brings up the function-menu."
  1496.   (interactive)
  1497.   (let ((find (symbol-value 'fume-find-next-function-name-method))
  1498.         (fnam)
  1499.         (flst '())
  1500.         (buffer-to-scan (current-buffer)))
  1501.     (save-excursion
  1502.       (goto-char (point-min))
  1503.       (cond (fume-scanning-message
  1504.              (message fume-scanning-message 0))
  1505.             (fume-rescanning-message
  1506.              (message fume-rescanning-message)))
  1507.       (while (setq fnam
  1508.                    (condition-case ()
  1509.                        (funcall find buffer-to-scan)
  1510.                      (error
  1511.                       ;; test for more possible fns after this error trap
  1512.                       (save-excursion
  1513.                         (re-search-forward
  1514.                          fume-function-name-regexp nil t)))))
  1515.         (cond ((listp fnam)
  1516.                (setq flst (cons fnam flst))
  1517.                (if fume-found-function-hook
  1518.                    (save-excursion (run-hooks 'fume-found-function-hook)))))
  1519.         (if fume-scanning-message
  1520.             (message fume-scanning-message (fume-relative-position))))
  1521.       (cond (fume-scanning-message
  1522.              (message "%s done" (format fume-scanning-message 100)))
  1523.             (fume-rescanning-message
  1524.              (message "%s done" fume-rescanning-message)))
  1525.       ;; make a copy of flst sorted by position in buffer
  1526.       (setq fume-modeline-funclist
  1527.             (nreverse
  1528.              (sort (fume-shallow-copy-list flst) 'fume-sort-by-position)))
  1529.       (if fume-sort-function
  1530.           (setq fume-funclist (sort flst fume-sort-function))
  1531.         (setq fume-funclist (nreverse flst)))
  1532.       (if fume-rescan-buffer-hook
  1533.           (run-hooks 'fume-rescan-buffer-hook))))
  1534.   (if popmenu
  1535.       (function-menu)
  1536.     (let ((fume-rescan-inhibit-p t))
  1537.       (fume-update-menubar-entry)))
  1538.   ;; Reset dirty flag
  1539.   (setq fume-funclist-dirty-p nil))
  1540.  
  1541. ;;; Routine to position cursor
  1542. ;;;
  1543. (defun fume-goto-function (fn pos)
  1544.   "Position cursor at function FN at location POS"
  1545.   (let ((orig-pos (point))
  1546.         (case-fold-search nil)
  1547.         (match-fn (cond ((string-match "DEFUN " fn) ; Emacs DEFUN declaration
  1548.                          (substring fn (match-end 0)))
  1549.                         ((string-match "^[ \t]*" fn) ; strip leading spaces
  1550.                          (substring fn (match-end 0)))
  1551.                         (t
  1552.                          fn))))
  1553.  
  1554.     (save-excursion
  1555.       (goto-char pos)
  1556.       (or (looking-at match-fn)
  1557.           (let ((fume-scanning-message nil))
  1558.             (fume-rescan-buffer)
  1559.             (setq pos (cdr-safe (assoc fn fume-funclist))))))
  1560.  
  1561.     (if pos
  1562.         (progn
  1563.           (goto-char pos)
  1564.           ;; possibly set mark
  1565.           (or (= orig-pos (point))
  1566.               (push-mark orig-pos (null fume-scanning-message)))
  1567.           (set-window-start
  1568.            (selected-window)
  1569.            (save-excursion
  1570.              (beginning-of-line
  1571.               (- 1 (or (and (numberp fume-fn-window-position)
  1572.                             (min (- (window-height) 2)
  1573.                                  fume-fn-window-position))
  1574.                        3)))
  1575.              (point))))
  1576.       (ding)
  1577.       (message "%s not found" fn)
  1578.       (function-menu))))
  1579.  
  1580. (if (and fume-running-xemacs (> emacs-minor-version 11))
  1581.     (defalias 'fume-event-window 'event-window)
  1582.   (defun fume-event-window (event)
  1583.     "More robust version of 'event-window'"
  1584.     (or (event-window event)
  1585.         (locate-window-from-coordinates
  1586.          (selected-frame) (list (event-x event) (event-y event)))
  1587.         (locate-window-from-coordinates
  1588.          (selected-frame) (list (event-x event) (1- (event-y event)))))))
  1589.  
  1590. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1591. ;;;;;;;;;;;;;;;;;;  The main entry points for this package  ;;;;;;;;;;;;;;;;
  1592. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1593.  
  1594. ;;; Interface to function-menu for mouse bindings only
  1595. ;;;
  1596. (defun mouse-function-menu (event)
  1597.   "Wrapper for mouse button bindings for function-menu"
  1598.   (interactive "e")
  1599.   (let ((currwin (selected-window)))
  1600.     (condition-case ()
  1601.         (progn
  1602.           (select-window (fume-event-window event))
  1603.           (let ((fume-auto-position-popup nil))
  1604.             (call-interactively 'function-menu)))
  1605.       (error (select-window currwin)))))
  1606.  
  1607. ;;; Interface for Key bindings
  1608. ;;;
  1609. (defun function-menu (&optional use-menubar)
  1610.   "Pop up a menu of functions for selection with the mouse.
  1611.  
  1612. With a prefix arg adds the menu to the current menubar.
  1613. Jumps to the selected function.  A mark is set at the old position,
  1614. so you can easily go back with C-u \\[set-mark-command]."
  1615.   (interactive "P")
  1616.  
  1617.   (setq use-menubar
  1618.         (and use-menubar fume-running-xemacs fume-not-tty current-menubar))
  1619.  
  1620.   (catch 'no-functions
  1621.     (or (fume-set-defaults)
  1622.         (if (not (interactive-p))
  1623.             (throw 'no-functions t)
  1624.           (error "func-menu does not support the mode \"%s\"" mode-name)))
  1625.  
  1626.     ;; Create a list for this buffer only if there isn't any.
  1627.     (or fume-funclist
  1628.         (if fume-rescan-inhibit-p
  1629.             (fume-remove-menubar-entry)
  1630.           (fume-rescan-buffer)))
  1631.     (or fume-funclist
  1632.         (if (not (interactive-p))
  1633.             (throw 'no-functions t)
  1634.           (error "No functions found in this buffer.")))
  1635.  
  1636.     ;; Rescan buffer trigger
  1637.     (fume-install-rescan-buffer-trigger)
  1638.  
  1639.     ;; Function name in modeline
  1640.     (fume-maybe-install-modeline-feature)
  1641.  
  1642.     ;; The rest of this routine works only for (Lucid) XEmacs
  1643.     (cond (fume-running-xemacs
  1644.            ;; Create the menu
  1645.            (let* ((count 0)
  1646.                   (index-method
  1647.                    (intern (format "fume-index-sublist-method-%d"
  1648.                                    fume-index-method)))
  1649.                   (function-menu
  1650.                    (mapcar
  1651.                     (function
  1652.                      (lambda (sublist)
  1653.                        (setq count (1+ count))
  1654.                        (cons (format "%s"
  1655.                                      (funcall index-method sublist count))
  1656.                              (mapcar
  1657.                               (function
  1658.                                (lambda (menu)
  1659.                                  (vector (format "%s" (car menu))
  1660.                                          (list 'fume-goto-function
  1661.                                                (car menu) (cdr menu))
  1662.                                          t)))
  1663.                               sublist))))
  1664.                     (fume-split fume-funclist fume-max-items))))
  1665.  
  1666.              (or (> count 1)
  1667.                  (setq function-menu (cdr (car function-menu))))
  1668.  
  1669.              (setq function-menu (cons
  1670.                                   (vector
  1671.                                    (concat "Rescan buffer :  "
  1672.                                            (buffer-name))
  1673.                                    (list 'fume-rescan-buffer
  1674.                                          (null use-menubar))
  1675.                                    t)
  1676.                                   (cons (vector "Display list of functions"
  1677.                                                 'fume-list-functions t)
  1678.                                         (cons "----" function-menu))))
  1679.  
  1680.              (cond (use-menubar
  1681.                     (fume-remove-menubar-entry)
  1682.                     (set-buffer-menubar (copy-sequence current-menubar))
  1683.                     (add-menu nil
  1684.                               fume-menubar-menu-name
  1685.                               (append
  1686.                                function-menu
  1687.                                (list
  1688.                                 "----"
  1689.                                 (vector "Remove Function Menu from menubar"
  1690.                                         'fume-remove-menubar-entry t)))
  1691.                               fume-menubar-menu-location))
  1692.  
  1693.                    ((and fume-not-tty   ; trap tty segmentation faults...
  1694.                          (not (popup-menu-up-p)))
  1695.                     (or (fume-update-menubar-entry)
  1696.                         (setq function-menu
  1697.                               (cons
  1698.                                (vector "Put Function Menu into menubar"
  1699.                                        (list 'function-menu t) t)
  1700.                                (cons "----" function-menu))))
  1701.  
  1702.                     (if fume-auto-position-popup
  1703.                         (if (< emacs-minor-version 12)
  1704.                             (set-mouse-position
  1705.                              (selected-frame)
  1706.                              (nth 0 (window-edges)) (nth 1 (window-edges)))
  1707.                           (set-mouse-position
  1708.                            (selected-window)
  1709.                            (nth 0 (window-pixel-edges))
  1710.                            (nth 1 (window-pixel-edges)))))
  1711.  
  1712.                     (popup-menu
  1713.                      (cons (concat "Function menu" (if (> count 1) "s"))
  1714.                            function-menu)))))))))
  1715.  
  1716. (defun fume-mouse-function-goto (event)
  1717.   "Goto function clicked on or prompt in minibuffer (with completion)."
  1718.   (interactive "@e")
  1719.   (goto-char (event-point event))
  1720.   (let ((fume-no-prompt-on-valid-default t))
  1721.     (fume-prompt-function-goto)))
  1722.  
  1723. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1724. ;;;;;;;;;;;;;;;;  Keyboard access to func-menu for tty users  ;;;;;;;;;;;;;;
  1725. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1726.  
  1727. ;;; Internal variables only
  1728. ;;;
  1729. (defvar fume-list-srcbuffer nil)
  1730. (defvar fume-list-reused-win-p nil)
  1731. (defvar fume-list-trampled-buffer nil)
  1732.  
  1733. ;;; Espen Skoglund <espensk@stud.cs.uit.no>
  1734. ;;; David Hughes <ukchugd@ukpmr.cs.philips.nl>
  1735. ;;;
  1736. (defun fume-prompt-function-goto (&optional other-window-p)
  1737.   "Goto function prompted for in minibuffer (with completion).
  1738. With prefix arg, jumps to function in a different window."
  1739.   (interactive "P")
  1740.   (and (interactive-p) current-prefix-arg (setq other-window-p t))
  1741.   (let* ((default-name (fume-what-looking-at))
  1742.          (OrigBuffer (current-buffer))
  1743.          (TargetBuffer
  1744.           (if (eq major-mode 'fume-list-mode) fume-list-srcbuffer OrigBuffer))
  1745.          (fume-no-prompt-on-valid-default
  1746.           (or fume-no-prompt-on-valid-default
  1747.               (eq major-mode 'fume-list-mode))))
  1748.     (switch-to-buffer TargetBuffer)
  1749.     ;; Create funclist and set defaults
  1750.     (cond ((null fume-funclist)
  1751.            (fume-set-defaults)
  1752.            (fume-rescan-buffer)))
  1753.     (let* (;; verify default-name is a valid function name
  1754.            (default-exists-p (assoc default-name fume-funclist))
  1755.            ;; Prompt for function name in minibuffer, unless there is a valid
  1756.            ;; function name at point & fume-no-prompt-on-valid-default set to t
  1757.            (function-name
  1758.             (if (and default-exists-p
  1759.                      fume-no-prompt-on-valid-default)
  1760.                 ""
  1761.               (completing-read
  1762.                (format "Goto function%s%s: "
  1763.                        (if other-window-p " other window" "")
  1764.                        (if default-exists-p
  1765.                            (concat " (" default-name ")")
  1766.                          ""))
  1767.                fume-funclist nil t)))
  1768.            ;; Use default function name if just RET was pressed
  1769.            (function-name (if (and default-exists-p (string= "" function-name))
  1770.                               default-name
  1771.                             function-name)))
  1772.       (switch-to-buffer OrigBuffer)
  1773.       ;; Goto function or just return if function name is empty string
  1774.       (cond ((not (string= "" function-name))
  1775.              (if other-window-p
  1776.                  (cond ((prog1 (one-window-p)
  1777.                           (switch-to-buffer-other-window TargetBuffer))
  1778.                         (other-window 1)
  1779.                         (shrink-window-if-larger-than-buffer)
  1780.                         (other-window 1)))
  1781.                (switch-to-buffer TargetBuffer))
  1782.              (fume-goto-function
  1783.               function-name (cdr (assoc function-name fume-funclist))))))))
  1784.  
  1785. (defun fume-prompt-function-goto-one-window ()
  1786.   (interactive)
  1787.   (delete-other-windows)
  1788.   (fume-prompt-function-goto))
  1789.  
  1790. (defun fume-prompt-function-goto-other-window ()
  1791.   (interactive)
  1792.   (let ((current-prefix-arg 1))
  1793.     (call-interactively 'fume-prompt-function-goto)))
  1794.  
  1795. (defun fume-list-functions-help ()
  1796.   (interactive)
  1797.   (sit-for 0)
  1798.   (message "Goto function: o=%s, g=%s, G=%s,   [q=quit, h=help]"
  1799.            "other window"
  1800.            "this window"
  1801.            "one window"))
  1802.  
  1803. (defun fume-list-functions-quit ()
  1804.   (interactive)
  1805.   (if (eq major-mode 'fume-list-mode)
  1806.       (kill-buffer (current-buffer)))
  1807.   (if fume-list-reused-win-p
  1808.       (condition-case ()
  1809.           (switch-to-buffer fume-list-trampled-buffer)
  1810.         (error nil))
  1811.     (or (one-window-p)
  1812.         (delete-window (selected-window))))
  1813.   (if (not (eq (current-buffer) fume-list-srcbuffer))
  1814.       (condition-case ()
  1815.           (select-window (get-buffer-window fume-list-srcbuffer))
  1816.         (error
  1817.          (condition-case ()
  1818.              (switch-to-buffer fume-list-srcbuffer)
  1819.            (error nil))))))
  1820.  
  1821. (defun fume-list-functions (&optional this-window)
  1822.   "Creates a temporary buffer listing functions found in the current buffer"
  1823.   (interactive "P")
  1824.   (cond ((or fume-function-name-regexp (fume-maybe-install-modeline-feature))
  1825.          (save-excursion
  1826.            (let ((srcbuffer (current-buffer)))
  1827.              (set-buffer (get-buffer-create fume-buffer-name))
  1828.              (let (buffer-read-only) (erase-buffer))
  1829.              (local-set-key "q" 'fume-list-functions-quit)
  1830.              (local-set-key "h" 'fume-list-functions-help)
  1831.              (local-set-key "?" 'fume-list-functions-help)
  1832.              (local-set-key "g" 'fume-prompt-function-goto)
  1833.              (local-set-key "G" 'fume-prompt-function-goto-one-window)
  1834.              (local-set-key "o" 'fume-prompt-function-goto-other-window)
  1835.              (setq buffer-read-only t
  1836.                    mode-name "Func-Menu"
  1837.                    major-mode 'fume-list-mode
  1838.                    fume-list-srcbuffer srcbuffer
  1839.                    fume-list-reused-win-p (not (one-window-p)))))
  1840.          (or fume-funclist (fume-rescan-buffer))
  1841.          (if fume-funclist
  1842.              (mapcar (function (lambda (p)
  1843.                                  (save-excursion
  1844.                                    (set-buffer fume-buffer-name)
  1845.                                    (let (buffer-read-only)
  1846.                                      (goto-char (point-max))
  1847.                                      (insert (concat (car p) "\n"))
  1848.                                      (set-buffer-modified-p nil)
  1849.                                      (goto-char (point-min))))))
  1850.                      fume-funclist))
  1851.          (cond ((interactive-p)
  1852.                 (if current-prefix-arg
  1853.                     (switch-to-buffer fume-buffer-name)
  1854.                   (switch-to-buffer-other-window fume-buffer-name)
  1855.                   (setq fume-list-trampled-buffer (other-buffer))
  1856.                   (or fume-list-reused-win-p
  1857.                       (shrink-window-if-larger-than-buffer)))
  1858.                 (fume-list-functions-help))))
  1859.         (t
  1860.          (error "Func-Menu is not operative in this buffer"))))
  1861.  
  1862. (provide 'func-menu)
  1863.